#include "mainwindow.h"
#include "ui_mainwindow.h"

extern "C"{
#include "sku622/sku622.h"
}

extern SKU622_TypeDef sku622_Data;



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QStringList serialNamePort;

    serialPort = new QSerialPort(this);
    connect(serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));/*手动连接槽函数*/

    ui->SerialCb->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->SerialCb->addItem(info.portName());
    }

    // 发送、接收计数清零
    sendNum = 0;
    recvNum = 0;
    // 状态栏
    QStatusBar *sBar = statusBar();
    // 状态栏的收、发计数标签
    lblSendNum = new QLabel(this);
    lblRecvNum = new QLabel(this);
    lblPortState = new QLabel(this);
    lblPortState->setText("Connected");
    //设置串口状态标签为绿色 表示已连接状态
    lblPortState->setStyleSheet("color:red");

    // 设置标签最小大小
    lblSendNum->setMinimumSize(100, 20);
    lblRecvNum->setMinimumSize(100, 20);
    lblPortState->setMinimumSize(550, 20);
    setNumOnLabel(lblSendNum, "S: ", sendNum);
    setNumOnLabel(lblRecvNum, "R: ", recvNum);
    // 从右往左依次添加
    sBar->addPermanentWidget(lblPortState);
    sBar->addPermanentWidget(lblSendNum);
    sBar->addPermanentWidget(lblRecvNum);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_CheckSerialBt_clicked()
{
    ui->SerialCb->clear();
    // 通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->SerialCb->addItem(info.portName());
    }
}

void MainWindow::copyQByteArrayToUint8Array(const QByteArray &byteArray, uint8_t *uint8Array)
{
    if (!byteArray.isEmpty())
    {
        // 使用memcpy直接拷贝内存
        std::memcpy(uint8Array, byteArray.constData(), byteArray.size());
    }
}

void MainWindow::ShowMeasureData(uint16_t selfId, uint16_t Measure_id, uint32_t dis, uint8_t checkSum)
{
    uint8_t DisplayLine = 0;
    static SKU622_TypeDef sku622_TableData[5];

    for (int var = 0; var < (int)sizeof(sku622_TableData); ++var)
    {
        if ((sku622_TableData[var].Self_id == selfId) && (sku622_TableData[var].Measure_id == Measure_id))
        {
            DisplayLine = var + 1;
            break;
        }
        else if((sku622_TableData[var].Self_id == 0) && (sku622_TableData[var].Measure_id != Measure_id))
        {
            DisplayLine = var + 1;
            sku622_TableData[var].Self_id = selfId;
            sku622_TableData[var].Measure_id = Measure_id;
            break;
        }
    }

    switch (DisplayLine) {
    case 1:
        ui->lineEdit1_1->setText(QString::number(selfId, 16).toUpper());
        ui->lineEdit1_2->setText(QString::number(Measure_id, 16).toUpper());
        ui->lineEdit1_3->setText(QString::number(dis, 10));
        ui->lineEdit1_4->setText(QString::number(checkSum, 16).toUpper());
        break;
    case 2:
        ui->lineEdit2_1->setText(QString::number(selfId, 16).toUpper());
        ui->lineEdit2_2->setText(QString::number(Measure_id, 16).toUpper());
        ui->lineEdit2_3->setText(QString::number(dis, 10));
        ui->lineEdit2_4->setText(QString::number(checkSum, 16).toUpper());
        break;
    case 3:
        ui->lineEdit3_1->setText(QString::number(selfId, 16).toUpper());
        ui->lineEdit3_2->setText(QString::number(Measure_id, 16).toUpper());
        ui->lineEdit3_3->setText(QString::number(selfId, 10));
        ui->lineEdit3_4->setText(QString::number(checkSum, 16).toUpper());
        break;
    case 4:
        ui->lineEdit4_1->setText(QString::number(selfId, 16).toUpper());
        ui->lineEdit4_2->setText(QString::number(Measure_id, 16).toUpper());
        ui->lineEdit4_3->setText(QString::number(dis, 10));
        ui->lineEdit4_4->setText(QString::number(checkSum, 16).toUpper());
        break;
    default:
        break;
    }


}


/*手动实现接收数据函数*/
void MainWindow::manual_serialPortReadyRead()
{
    QByteArray recBuf = serialPort->readAll();;
    QString str_rev;

    copyQByteArrayToUint8Array(recBuf, U8_ReceiveBuff);
    SKU622_UnpackBuffer(U8_ReceiveBuff, (uint16_t)(recBuf.size()));
    qDebug() << "This device id: " << sku622_Data.Self_id << " \r\n";
    qDebug() << "Tested device id: " << sku622_Data.Measure_id << " \r\n";
    qDebug() << "Distance: " << SKU622_GetDis() << "cm \r\n";

    ShowMeasureData(sku622_Data.Self_id, sku622_Data.Measure_id, SKU622_GetDis(), 0);

    // 接收字节计数
    recvNum += recBuf.size();
    // 状态栏显示计数值
    setNumOnLabel(lblRecvNum, "R: ", recvNum);

    // 16进制显示，并转换为大写
    QString str1 = recBuf.toHex().toUpper();//.data();
    // 添加空格
    QString str2;
    for(int i = 0; i<str1.length (); i+=2)
    {
        str2 += str1.mid(i, 2);
        str2 += " ";
    }
    if(ui->chk_rec_timestamp->checkState() == Qt::Checked)
    {
        QDateTime nowtime = QDateTime::currentDateTime();
        str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
        str_rev += str2.append("\r\n");
    }
    else
    {
        if(ui->chk_rec_line->checkState() == Qt::Checked)
            str_rev += str2.append("\r\n");
        else
            str_rev = str2;
    }

    ui->RecevieEdit->insertPlainText(str_rev);
    ui->RecevieEdit->moveCursor(QTextCursor::End);
}

void MainWindow::on_OpenSerialBt_clicked()
{
    /*串口初始化*/
    QSerialPort::BaudRate baudRate;
    QSerialPort::DataBits dataBits;
    QSerialPort::StopBits stopBits;
    QSerialPort::Parity checkBits;

    // 获取串口波特率
    // baudRate = ui->baundrateCb->currentText().toInt();直接字符串转换为 int 的方法
    if(ui->BaundrateCb->currentText()=="9600")
        baudRate=QSerialPort::Baud9600;
    else if(ui->BaundrateCb->currentText()=="115200")
        baudRate=QSerialPort::Baud115200;

    // 获取串口数据位
    if(ui->DataBitCb->currentText()=="8")
        dataBits=QSerialPort::Data8;
    else if(ui->DataBitCb->currentText()=="7")
        dataBits=QSerialPort::Data7;
    else if(ui->DataBitCb->currentText()=="6")
        dataBits=QSerialPort::Data6;

    // 获取串口停止位
    if(ui->StopBitCb->currentText()=="1")
        stopBits=QSerialPort::OneStop;
    else if(ui->StopBitCb->currentText()=="1.5")
        stopBits=QSerialPort::OneAndHalfStop;
    else if(ui->StopBitCb->currentText()=="2")
        stopBits=QSerialPort::TwoStop;

    // 获取串口奇偶校验位
    if(ui->CheckBitCb->currentText() == "None"){
        checkBits = QSerialPort::NoParity;
    }else if(ui->CheckBitCb->currentText() == "奇校验"){
        checkBits = QSerialPort::OddParity;
    }else if(ui->CheckBitCb->currentText() == "偶校验"){
        checkBits = QSerialPort::EvenParity;
    }else{

    }

    // 初始化串口属性，设置 端口号、波特率、数据位、停止位、奇偶校验位数
    serialPort->setPortName(ui->SerialCb->currentText());
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(dataBits);
    serialPort->setStopBits(stopBits);
    serialPort->setParity(checkBits);

    // 根据初始化好的串口属性，打开串口
    // 如果打开成功，反转打开按钮显示和功能。打开失败，无变化，并且弹出错误对话框。
    if(ui->OpenSerialBt->text() == "打开串口"){
        if(serialPort->open(QIODevice::ReadWrite) == true){
            //QMessageBox::
            ui->OpenSerialBt->setText("关闭串口");
            // 让端口号下拉框不可选，避免误操作（选择功能不可用，控件背景为灰色）
            ui->SerialCb->setEnabled(false);
        }else{
            QMessageBox::critical(this, "错误提示", "串口打开失败！！！\r\n该串口可能被占用\r\n请选择正确的串口");
        }
        //statusBar 状态栏显示端口状态
        QString sm = "%1 OPENED, %2, 8, NONE, 1";
        QString status = sm.arg(serialPort->portName()).arg(serialPort->baudRate());
        lblPortState->setText(status);
        lblPortState->setStyleSheet("color:green");
    }else{
        serialPort->close();
        ui->OpenSerialBt->setText("打开串口");
        // 端口号下拉框恢复可选，避免误操作
        ui->SerialCb->setEnabled(true);
        //statusBar 状态栏显示端口状态
        QString sm = "%1 CLOSED";
        QString status = sm.arg(serialPort->portName());
        lblPortState->setText(status);
        lblPortState->setStyleSheet("color:red");
    }
}


void MainWindow::on_CleanBt_clicked()
{
    ui->RecevieEdit->clear();

    ui->lineEdit1_1->clear();
    ui->lineEdit1_2->clear();
    ui->lineEdit1_3->clear();
    ui->lineEdit1_4->clear();

    ui->lineEdit2_1->clear();
    ui->lineEdit2_2->clear();
    ui->lineEdit2_3->clear();
    ui->lineEdit2_4->clear();

    ui->lineEdit3_1->clear();
    ui->lineEdit3_2->clear();
    ui->lineEdit3_3->clear();
    ui->lineEdit3_4->clear();

    ui->lineEdit4_1->clear();
    ui->lineEdit4_2->clear();
    ui->lineEdit4_3->clear();
    ui->lineEdit4_4->clear();

    // 清除发送、接收字节计数
    sendNum = 0;
    recvNum = 0;
    // 状态栏显示计数值
    setNumOnLabel(lblSendNum, "S: ", sendNum);
    setNumOnLabel(lblRecvNum, "R: ", recvNum);
}

// 状态栏标签显示计数值
void MainWindow::setNumOnLabel(QLabel *lbl, QString strS, long num)
{
    // 标签显示
    QString strN;
    strN.asprintf("%ld", num);
    QString str = strS + strN;
    lbl->setText(str);
}


























